<template>
  <div class="rsa-tool">
    <h2>RSA 加解密</h2>
    
    <!-- 生成公私钥对部分 -->
    <section class="key-generation">
      <h3>生成密钥对</h3>
      <div class="input-group">
        <label for="keySize">密钥长度 (bits):</label>
        <input id="keySize" type="number" v-model.number="keySize" min="512" step="128" />
      </div>
      <div class="input-group">
        <label for="exponent">公钥指数:</label>
        <input id="exponent" type="number" v-model.number="exponent" readonly />
      </div>
      <button @click="generateKeys">生成密钥对</button>
      <div class="key-output" v-if="publicKey || privateKey">
        <h4>公钥 (Public Key):</h4>
        <textarea v-model="publicKey" rows="6" readonly></textarea>
        <h4>私钥 (Private Key):</h4>
        <textarea v-model="privateKey" rows="6" readonly></textarea>
      </div>
    </section>
    
    <!-- 自定义密钥对部分 -->
    <section class="custom-key-section">
      <h3>自定义密钥对</h3>
      <div class="input-group">
        <label for="customPublicKey">公钥:</label>
        <textarea id="customPublicKey" v-model="customPublicKey" rows="4" placeholder="粘贴公钥"></textarea>
      </div>
      <div class="input-group">
        <label for="customPrivateKey">私钥:</label>
        <textarea id="customPrivateKey" v-model="customPrivateKey" rows="4" placeholder="粘贴私钥"></textarea>
      </div>
      <button @click="loadCustomKeys">加载自定义密钥</button>
    </section>
    
    <!-- 加解密操作部分 -->
    <section class="encryption-section">
      <h3>加解密操作</h3>
      <div class="input-group">
        <label for="rsaInput">输入文本:</label>
        <textarea id="rsaInput" v-model="rsaInput" rows="4" placeholder="加密时填写明文，解密时填写密文 (Base64)" ></textarea>
      </div>
      <div class="input-group">
        <label for="rsaScheme">加解密方式:</label>
        <select id="rsaScheme" v-model="rsaScheme">
          <option value="PKCS1">RSAES-PKCS1-V1_5 (PKCS1)</option>
          <option value="OAEP">RSA-OAEP</option>
        </select>
      </div>
      <div class="btn-group">
        <button @click="encryptRSA">加密</button>
        <button @click="decryptRSA">解密</button>
      </div>
      <div class="output-group" v-if="rsaResult">
        <h4>结果:</h4>
        <textarea v-model="rsaResult" rows="4" readonly></textarea>
      </div>
      <p v-if="rsaError" class="error">{{ rsaError }}</p>
    </section>
  </div>
</template>

<script>
import * as forge from 'node-forge';

export default {
  name: 'RSATool',
  data() {
    return {
      // 密钥生成相关参数
      keySize: 2048,
      exponent: 65537,
      publicKey: '',
      privateKey: '',
      // 自定义密钥对
      customPublicKey: '',
      customPrivateKey: '',
      // 加解密操作
      rsaInput: '',
      rsaResult: '',
      rsaScheme: 'PKCS1', // 可选 "PKCS1" 或 "OAEP"
      rsaError: ''
    };
  },
  methods: {
    generateKeys() {
      this.rsaError = '';
      // 使用 node-forge 异步生成 RSA 密钥对
      forge.pki.rsa.generateKeyPair({ bits: this.keySize, e: this.exponent }, (err, keypair) => {
        if (err) {
          this.rsaError = '生成密钥失败：' + err.message;
        } else {
          this.publicKey = forge.pki.publicKeyToPem(keypair.publicKey);
          this.privateKey = forge.pki.privateKeyToPem(keypair.privateKey);
        }
      });
    },
    loadCustomKeys() {
      // 若用户自定义输入了公钥/私钥，则加载到当前使用的密钥中
      if (this.customPublicKey) {
        this.publicKey = this.customPublicKey;
      }
      if (this.customPrivateKey) {
        this.privateKey = this.customPrivateKey;
      }
    },
    encryptRSA() {
      if (!this.publicKey) {
        this.rsaError = '请先生成密钥对或粘贴公钥';
        return;
      }
      try {
        this.rsaError = '';
        const pubKey = forge.pki.publicKeyFromPem(this.publicKey);
        // 根据用户选择的加解密方式，确定使用的方案
        const scheme = this.rsaScheme === 'PKCS1' ? 'RSAES-PKCS1-V1_5' : 'RSA-OAEP';
        // 加密，得到结果为二进制字符串，再转换为 Base64 便于显示和传递
        const encrypted = pubKey.encrypt(this.rsaInput, scheme);
        this.rsaResult = forge.util.encode64(encrypted);
      } catch (error) {
        this.rsaError = '加密失败：' + error.message;
      }
    },
    decryptRSA() {
      if (!this.privateKey) {
        this.rsaError = '请先生成密钥对或粘贴私钥';
        return;
      }
      try {
        this.rsaError = '';
        const privKey = forge.pki.privateKeyFromPem(this.privateKey);
        const scheme = this.rsaScheme === 'PKCS1' ? 'RSAES-PKCS1-V1_5' : 'RSA-OAEP';
        // 先将 Base64 编码的密文解码为二进制字符串，然后解密
        const encryptedBytes = forge.util.decode64(this.rsaInput);
        const decrypted = privKey.decrypt(encryptedBytes, scheme);
        this.rsaResult = decrypted;
      } catch (error) {
        this.rsaError = '解密失败：' + error.message;
      }
    }
  }
};
</script>

<style scoped>
.rsa-tool {
  max-width: 600px;
  margin: 0 auto;
  text-align: center;
}
section {
  margin: 20px 0;
  border: 1px solid #ccc;
  padding: 15px;
  border-radius: 4px;
}
.input-group {
  margin: 10px 0;
  text-align: left;
}
.input-group label {
  display: block;
  margin-bottom: 5px;
  font-weight: bold;
}
.input-group input,
.input-group textarea,
.input-group select {
  width: 100%;
  padding: 8px;
  box-sizing: border-box;
  border: 1px solid #ccc;
  border-radius: 4px;
}
.btn-group {
  margin: 10px 0;
}
.btn-group button {
  padding: 10px 20px;
  margin: 5px;
  background-color: #3498db;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.3s;
}
.btn-group button:hover {
  background-color: #2980b9;
}
.key-output textarea,
.output-group textarea {
  width: 100%;
  padding: 8px;
  box-sizing: border-box;
  border: 1px solid #ccc;
  border-radius: 4px;
  margin: 5px 0;
  resize: vertical;
}
.error {
  color: red;
  margin-top: 10px;
}
</style> 